// 缓存工具类
interface CacheItem<T = unknown> {
  data: T;
  timestamp: number;
  ttl: number; // Time to live in milliseconds
}

class CacheManager {
  private cache = new Map<string, CacheItem>();
  private defaultTTL = 5 * 60 * 1000; // 5 minutes default

  set<T>(key: string, data: T, ttl: number = this.defaultTTL): void {
    const item: CacheItem<T> = {
      data,
      timestamp: Date.now(),
      ttl,
    };
    this.cache.set(key, item);
  }

  get<T>(key: string): T | null {
    const item = this.cache.get(key);
    if (!item) return null;

    const now = Date.now();
    if (now - item.timestamp > item.ttl) {
      this.cache.delete(key);
      return null;
    }

    return item.data as T;
  }

  has(key: string): boolean {
    return this.get(key) !== null;
  }

  delete(key: string): boolean {
    return this.cache.delete(key);
  }

  clear(): void {
    this.cache.clear();
  }

  // 清理过期缓存
  cleanup(): void {
    const now = Date.now();
    for (const [key, item] of this.cache.entries()) {
      if (now - item.timestamp > item.ttl) {
        this.cache.delete(key);
      }
    }
  }

  // 获取缓存统计信息
  getStats(): { size: number; keys: string[] } {
    return {
      size: this.cache.size,
      keys: Array.from(this.cache.keys()),
    };
  }
}

// 全局缓存实例
export const cache = new CacheManager();

// 缓存装饰器
export function withCache<T extends (...args: any[]) => any>(
  fn: T,
  keyGenerator?: (...args: Parameters<T>) => string,
  ttl: number = 5 * 60 * 1000
): T {
  return ((...args: Parameters<T>) => {
    const cacheKey = keyGenerator
      ? keyGenerator(...args)
      : `${fn.name}:${JSON.stringify(args)}`;

    const cached = cache.get(cacheKey);
    if (cached !== null) {
      return cached;
    }

    const result = fn(...args);
    cache.set(cacheKey, result, ttl);
    return result;
  }) as T;
}

// 内存缓存 Hook
export function useCache<T = unknown>(
  key: string,
  fetchFn: () => Promise<T>,
  options: {
    ttl?: number;
    enabled?: boolean;
    staleWhileRevalidate?: boolean;
  } = {}
) {
  const { ttl = 5 * 60 * 1000, enabled = true, staleWhileRevalidate = true } = options;

  const [data, setData] = React.useState<T | null>(null);
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState<Error | null>(null);

  React.useEffect(() => {
    if (!enabled) return;

    const fetchData = async () => {
      setLoading(true);
      setError(null);

      try {
        // 检查缓存
        const cached = cache.get<T>(key);
        if (cached) {
          setData(cached);

          // 如果启用了过期时刷新，在后台更新缓存
          if (staleWhileRevalidate) {
            fetchFn().then(freshData => {
              cache.set(key, freshData, ttl);
              setData(freshData);
            }).catch(err => {
              console.error('Background refresh failed:', err);
            });
          }
          setLoading(false);
          return;
        }

        // 没有缓存，获取数据
        const freshData = await fetchFn();
        cache.set(key, freshData, ttl);
        setData(freshData);
      } catch (err) {
        setError(err as Error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [key, fetchFn, ttl, enabled, staleWhileRevalidate]);

  const mutate = React.useCallback((newData: T | ((oldData: T | null) => T)) => {
    const updatedData = typeof newData === 'function'
      ? (newData as (oldData: T | null) => T)(data)
      : newData;

    setData(updatedData);
    cache.set(key, updatedData, ttl);
  }, [key, data, ttl]);

  const clearCache = React.useCallback(() => {
    setData(null);
    cache.delete(key);
  }, [key]);

  return {
    data,
    loading,
    error,
    mutate,
    clearCache,
  };
}

// 本地存储缓存
export class LocalStorageCache {
  private prefix: string;

  constructor(prefix: string = 'app_cache_') {
    this.prefix = prefix;
  }

  private getKey(key: string): string {
    return `${this.prefix}${key}`;
  }

  set<T>(key: string, data: T, ttl: number = this.defaultTTL): void {
    const item: CacheItem<T> = {
      data,
      timestamp: Date.now(),
      ttl,
    };

    try {
      localStorage.setItem(this.getKey(key), JSON.stringify(item));
    } catch (error) {
      console.error('Failed to cache to localStorage:', error);
      // 如果存储失败，清理一些旧数据
      this.cleanup();
      try {
        localStorage.setItem(this.getKey(key), JSON.stringify(item));
      } catch (error) {
        console.error('Still failed to cache after cleanup:', error);
      }
    }
  }

  get<T>(key: string): T | null {
    try {
      const itemStr = localStorage.getItem(this.getKey(key));
      if (!itemStr) return null;

      const item: CacheItem<T> = JSON.parse(itemStr);
      const now = Date.now();

      if (now - item.timestamp > item.ttl) {
        localStorage.removeItem(this.getKey(key));
        return null;
      }

      return item.data;
    } catch (error) {
      console.error('Failed to get from localStorage cache:', error);
      return null;
    }
  }

  delete(key: string): void {
    try {
      localStorage.removeItem(this.getKey(key));
    } catch (error) {
      console.error('Failed to delete from localStorage cache:', error);
    }
  }

  clear(): void {
    try {
      const keys = Object.keys(localStorage);
      for (const key of keys) {
        if (key.startsWith(this.prefix)) {
          localStorage.removeItem(key);
        }
      }
    } catch (error) {
      console.error('Failed to clear localStorage cache:', error);
    }
  }

  cleanup(): void {
    try {
      const keys = Object.keys(localStorage);
      const now = Date.now();

      for (const key of keys) {
        if (key.startsWith(this.prefix)) {
          try {
            const itemStr = localStorage.getItem(key);
            if (itemStr) {
              const item: CacheItem = JSON.parse(itemStr);
              if (now - item.timestamp > item.ttl) {
                localStorage.removeItem(key);
              }
            }
          } catch (error) {
            // 如果解析失败，删除该缓存项
            localStorage.removeItem(key);
          }
        }
      }
    } catch (error) {
      console.error('Failed to cleanup localStorage cache:', error);
    }
  }

  private get defaultTTL(): number {
    return 24 * 60 * 60 * 1000; // 24 hours for localStorage
  }
}

// 本地存储缓存实例
export const localStorageCache = new LocalStorageCache();

// API 响应缓存 Hook
export function useApiCache<T = unknown>(
  key: string,
  apiCall: () => Promise<T>,
  options: {
    ttl?: number;
    enabled?: boolean;
    refetchOnWindowFocus?: boolean;
    refetchOnReconnect?: boolean;
  } = {}
) {
  const {
    ttl = 5 * 60 * 1000,
    enabled = true,
    refetchOnWindowFocus = true,
    refetchOnReconnect = true
  } = options;

  const result = useCache(key, apiCall, { ttl, enabled });

  React.useEffect(() => {
    if (!refetchOnWindowFocus) return;

    const handleFocus = () => {
      result.mutate(apiCall());
    };

    window.addEventListener('focus', handleFocus);
    return () => window.removeEventListener('focus', handleFocus);
  }, [refetchOnWindowFocus, apiCall, result.mutate]);

  React.useEffect(() => {
    if (!refetchOnReconnect) return;

    const handleOnline = () => {
      result.mutate(apiCall());
    };

    window.addEventListener('online', handleOnline);
    return () => window.removeEventListener('online', handleOnline);
  }, [refetchOnReconnect, apiCall, result.mutate]);

  return result;
}